#include "qubit.h"
using namespace std;


// 默认构造 n 维零态矢量
qubit::qubit(int n_):n(n_){
    v = new complex<type>[n];
    if ( v == NULL )
        cout << "error in construction" << endl;
    for ( int i = 0; i < n; ++ i )
        v[i] = 0;
    v[0] = 1;
}

// 构造态矢量
qubit::qubit(complex<type> * v_, int n_):n(n_){
    v = new complex<type>[n];
    if ( v == NULL )
        cout << "error in construction" << endl;
    for ( int i = 0; i < n; ++ i )
        v[i] = v_[i];
}

// copy constructor
qubit::qubit(const qubit & q):n(q.n){
    v = new complex<type>[n];
    if ( v == NULL )
        cout << "error in construction" << endl;
    for ( int i = 0; i < n; ++ i ){
        v[i] = q.v[i];
    }
}

qubit::~qubit(){
    delete [] v;
}

qubit & qubit::operator=(const qubit & a){  //copy assignment
    if ( this != &a ){
        delete [] v;
        n = a.n;
        v = new complex<type>[n];
        for ( int i = 0; i < n; ++ i )
            v[i] = a.v[i];
    }
    return * this;
}

// 获取矢量维度
int qubit::getDim(){
    cout << "n = " << n << endl;
    return n;
}

string to_string(int num, unsigned wide){
    string ket = "|";
    char s[10];
    itoa(num, s, 2);
    for ( unsigned i = 0; i < wide - strlen(s); ++ i )
        ket += '0';
    for ( unsigned i = 0; i < strlen(s); ++ i )
        ket += s[i];
    ket += '>';
    return ket;
}

// 获取概率幅
void qubit::getAmplitude(){
    cout << '[';
    for ( int i = 0; i < n; ++ i ){
        if ( v[i] != complex<type>{0} )
            cout << to_string(i, log2(n)) << v[i] << endl;
    }
    cout << ']' << endl;
    return;
}

// 张量积
qubit tensorProduct(qubit & a, qubit & b){
    qubit q(a.n * b.n);
    for ( int i = 0; i < a.n; ++ i )
        for ( int j = 0; j < b.n; ++ j )
            q.v[ i * b.n + j ] = a.v[i] * b.v[j];
    return q;
}

// 线性变换
void linearTransform(gate & g, qubit & b){
    qubit q(g.ro);
    for ( int i = 0; i < g.ro; ++ i ){
        q.v[i] = 0;
        for ( int j = 0; j < g.co; ++ j ){
            q.v[i] += g.m[i][j] * b.v[j];
        }
    }
    b = q;
    return;
}

// // 共轭
// qubit qubit::conjugate(const qubit * a){
//     complex<type> * v = new complex<type>[a->n];
//     for ( int i = 0; i < a->n; ++ i )
//         v[i] = conj(a->v[i]);
//     return qubit{a->n, v};
// }

// // 内积
// complex<type> qubit::innerProduct(qubit * a, qubit * b){
//     complex<type> c{0};
//     for ( int i = 0; i < a->n; ++ i )
//         c = c + a->v[i] * b->v[i];
//     return c;
// }

